package handler

import (
	"context"
	"errors"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/types/known/emptypb"
	"gorm.io/gorm"
	"project07_resum_srv/src/global"
	"project07_resum_srv/src/model"
	"project07_resum_srv/src/proto"
)

func Paginate(page, pageSize int) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {

		if page == 0 {
			page = 1
		}

		switch {
		case pageSize > 100:
			pageSize = 100
		case pageSize <= 0:
			pageSize = 10
		}
		offset := (page - 1) * pageSize
		return db.Offset(offset).Limit(pageSize)
	}
}

func UserModel2UserInfoResponse(resume model.Resume) proto.ResumeInfo {
	return proto.ResumeInfo{
		Name:           resume.Name,
		Age:            int32(resume.Age),
		Sex:            resume.Sex,
		HouseKeepingId: int32(resume.HouseKeepingId),
		WorkExp:        resume.WorkExp,
		Describe:       resume.Describe,
		Reword:         int32(resume.Reword),
		HouseKeeping: &proto.HouseKeepingInfo{
			HouseKeepingId: int32(resume.HouseKeeping.ID),
			Qualification:  resume.HouseKeeping.Qualification,
			Sex:            int32(resume.HouseKeeping.Sex),
			WorkStartDate:  resume.HouseKeeping.WorkStartDate,
			EndDate:        resume.HouseKeeping.WorkEndDate,
		},
	}
}

// GetResumeList(context.Context, *PageInfo) (*ResumeRes, error)
// GetResumeByResumeId(context.Context, *ResumeId) (*ResumeInfo, error)
// GetResumeByHouseKeepingId(context.Context, *HouseKeepingId) (*ResumeRes, error)
// GetResumeByResumeName(context.Context, *ResumeName) (*ResumeRes, error)
// CreateResume(context.Context, *CreateResumeReq) (*emptypb.Empty, error)
// UpdateResume(context.Context, *UpdateResumeReq) (*emptypb.Empty, error)
// DeleteResumeByResumeId(context.Context, *ResumeId) (*emptypb.Empty, error)
type ResumeService struct {
}

func (resumeService *ResumeService) DeleteResumeByResumeId(ctx context.Context, req *proto.ResumeId) (*emptypb.Empty, error) {
	tx := global.Db.Begin()
	var resume model.Resume
	tx.Where("resume.id = ?", req.Id).Find(&resume)
	if tx.RowsAffected == 0 {
		tx.Rollback()
		return nil, status.Error(codes.NotFound, "没有对应目标")
	}
	if tx.Error == gorm.ErrRecordNotFound {
		tx.Rollback()
		return nil, status.Error(codes.NotFound, "没有对应目标")
	}

	tx.Where("resume.id = ?", req.Id).Delete(&resume)
	if tx.Error != nil {
		tx.Rollback()
		return nil, status.Error(codes.Internal, "删除失败")
	}
	tx.Commit()
	return &emptypb.Empty{}, nil
}

func (resumeService *ResumeService) UpdateResume(ctx context.Context, req *proto.UpdateResumeReq) (*emptypb.Empty, error) {
	tx := global.Db.Begin()
	var resume model.Resume
	tx.Where("resume.id = ?", req.ResumeId).Find(&resume)
	if tx.RowsAffected == 0 {
		tx.Rollback()
		return nil, status.Error(codes.NotFound, "没有对应目标")
	}
	if tx.Error == gorm.ErrRecordNotFound {
		tx.Rollback()
		return nil, status.Error(codes.NotFound, "没有对应目标")
	}
	if int32(resume.HouseKeepingId) != req.HouseId {
		tx.Rollback()
		return nil, status.Error(codes.InvalidArgument, "不是对应的用户")
	}

	resume.Age = int(req.Age)
	resume.Sex = req.Sex
	resume.Name = req.Name
	resume.WorkExp = req.WorkExp
	resume.Reword = int(req.Reword)
	resume.Describe = req.Describe

	tx.Save(&resume)
	if tx.Error != nil {
		tx.Rollback()
		return nil, status.Error(codes.Internal, "修改失败")
	}
	tx.Commit()
	return &emptypb.Empty{}, nil
}

func (resumeService *ResumeService) CreateResume(ctx context.Context, req *proto.CreateResumeReq) (*emptypb.Empty, error) {
	tx := global.Db.Begin()
	var resume model.Resume
	resume.Sex = req.Sex
	resume.Name = req.Name
	resume.Age = int(req.Age)
	resume.WorkExp = req.WorkExp
	resume.HouseKeepingId = int(req.HouseKeepingId)
	resume.Describe = req.Describe
	resume.Reword = int(req.Reword)
	tx.Create(&resume)
	if tx.Error != nil {
		tx.Rollback()
		return nil, status.Error(codes.Internal, "创建失败")
	}
	tx.Commit()
	return &emptypb.Empty{}, nil
}

func (resumeService *ResumeService) GetResumeByResumeName(ctx context.Context, req *proto.ResumeName) (*proto.ResumeRes, error) {
	var resume []model.Resume
	tx := global.Db.Begin()
	if tx.Error != nil {
		panic(errors.New("事务加载异常"))
	}
	tx.Model(&model.Resume{}).Preload("HouseKeeping").
		Scopes(Paginate(int(req.Page.Pn), int(req.Page.PSize))).
		Joins("join house_keeping on house_keeping.id = resume.owner_id").
		Where("house_keeping.name like '%?%'", req.Name).Find(&resume)
	if tx.Error != nil {
		if tx.Error == gorm.ErrRecordNotFound {
			tx.Rollback()
			return nil, status.Error(codes.NotFound, "未找到")
		}
		if tx.RowsAffected == 0 {
			tx.Rollback()
			return nil, status.Error(codes.NotFound, "没有数据")
		}
	}
	tx.Commit()

	var res proto.ResumeRes
	for _, v := range resume {
		value := UserModel2UserInfoResponse(v)
		res.Res = append(res.Res, &value)
	}
	return &res, nil

}

func (resumeService *ResumeService) GetResumeByHouseKeepingId(ctx context.Context, req *proto.HouseKeepingId) (*proto.ResumeRes, error) {
	var resume []model.Resume
	tx := global.Db.Begin()
	if tx.Error != nil {
		panic(errors.New("事务加载异常"))
	}
	tx.Model(&model.Resume{}).Preload("HouseKeeping").
		Scopes(Paginate(int(req.Page.Pn), int(req.Page.PSize))).
		Joins("join house_keeping on house_keeping.id = resume.owner_id").
		Where("house_keeping.id = ?", req.Id).Find(&resume)
	if tx.Error != nil {
		if tx.Error == gorm.ErrRecordNotFound {
			tx.Rollback()
			return nil, status.Error(codes.NotFound, "未找到")
		}
		if tx.RowsAffected == 0 {
			tx.Rollback()
			return nil, status.Error(codes.NotFound, "没有数据")
		}
	}
	tx.Commit()

	var res proto.ResumeRes
	for _, v := range resume {
		value := UserModel2UserInfoResponse(v)
		res.Res = append(res.Res, &value)
	}
	return &res, nil
}

func (resumeService *ResumeService) GetResumeByResumeId(ctx context.Context, req *proto.ResumeId) (*proto.ResumeInfo, error) {
	var resume model.Resume
	tx := global.Db.Begin()
	if tx.Error != nil {
		panic(errors.New("事务加载异常"))
	}
	tx.Model(&model.Resume{}).Preload("HouseKeeping").
		Joins("join house_keeping on house_keeping.id = resume.owner_id").
		Where("resume.id = ?", req.Id).First(&resume)
	if tx.Error != nil {
		if tx.Error == gorm.ErrRecordNotFound {
			tx.Rollback()
			return nil, status.Error(codes.NotFound, "未找到")
		}
		if tx.RowsAffected == 0 {
			tx.Rollback()
			return nil, status.Error(codes.NotFound, "没有数据")
		}
	}
	tx.Commit()

	result := UserModel2UserInfoResponse(resume)
	return &result, nil
}

func (resumeService *ResumeService) GetResumeList(ctx context.Context, info *proto.PageInfo) (*proto.ResumeRes, error) {
	var resume []model.Resume
	tx := global.Db.Begin()
	if tx.Error != nil {
		panic(errors.New("事务加载异常"))
	}
	tx.Model(&model.Resume{}).Preload("HouseKeeping").
		Joins("join house_keeping on house_keeping.id = resume.owner_id").
		Find(&resume)
	if tx.Error != nil {
		if tx.Error == gorm.ErrRecordNotFound {
			tx.Rollback()
			return nil, status.Error(codes.NotFound, "未找到")
		}
		if tx.RowsAffected == 0 {
			tx.Rollback()
			return nil, status.Error(codes.NotFound, "没有数据")
		}
	}
	tx.Commit()

	var res proto.ResumeRes
	for _, v := range resume {
		value := UserModel2UserInfoResponse(v)
		res.Res = append(res.Res, &value)
	}

	return &res, nil
}

func (resumeService *ResumeService) GetResumeFilePath(ctx context.Context, req *proto.ResumeId) (*proto.FilePathInfo, error) {
	var resume model.Resume
	tx := global.Db.Begin()
	tx.Model(&model.Resume{}).Where("resume.id = ?", req.Id).First(&resume)
	if tx.Error != nil {
		tx.Rollback()
		if tx.Error == gorm.ErrRecordNotFound {
			return nil, errors.New("未找到对应条目")
		}
		return nil, errors.New("内部错误")
	}
	tx.Commit()

	return &proto.FilePathInfo{FilePathName: resume.ResumePath}, nil
}

func (resumeService *ResumeService) SetResumeFilePath(ctx context.Context, req *proto.SetResumeFileReq) (*emptypb.Empty, error) {
	var resume model.Resume
	tx := global.Db.Begin()
	//tx.Where("resume.id = ?", req.ResumeId).First(&resume)
	if tx.Error != nil {
		tx.Rollback()
		return nil, status.Errorf(codes.Internal, "内部错误")
	}
	resume.ResumePath = req.Path
	tx.Save(&resume)
	if tx.Error != nil {
		tx.Rollback()
		return nil, status.Errorf(codes.Internal, "内部错误")
	}

	tx.Commit()
	return &emptypb.Empty{}, nil
}

func (resumeService *ResumeService) GetResumeNum(ctx context.Context, req *proto.UserId) (*proto.FileNameInfo, error) {
	var housekeeping model.HouseKeeping
	tx := global.Db.Begin()
	tx.Where("user.id = ?", req.Uid).First(&housekeeping)
	if tx.Error != nil {
		tx.Rollback()
		return nil, status.Errorf(codes.Internal, "内部错误")
	}
	return &proto.FileNameInfo{FileName: housekeeping.Separator}, nil
}

func (resumeService *ResumeService) GetFilenamehash(ctx context.Context, req *proto.UserId) (*proto.FilenamehashRes, error) {
	var housekeeping model.HouseKeeping
	tx := global.Db.Begin()
	tx.Where("user.id = ?", req.Uid).First(&housekeeping)
	if tx.Error != nil {
		tx.Rollback()
		return nil, status.Errorf(codes.Internal, "内部错误")
	}
	return &proto.FilenamehashRes{Filenamehash: housekeeping.Separator}, nil
}
func (ResumeService *ResumeService) SavePathName(ctx context.Context, req *proto.PathReq) {
	var housekeeping model.HouseKeeping
	var resume model.Resume
	tx := global.Db
	tx.Where("user.id = ?", req.UserId).First(&housekeeping)
	tx.Where("resume.house_keeping_id = ?", housekeeping.ID).Find(&resume)
	resume.ResumePath = req.Pathname
	tx.Save(&resume)
}
func Uploadhash() {

}
